<template>
  <view v-show="show" class="t-wrapper" @touchmove.stop.prevent="moveHandle">
    <view class="t-mask" :class="{active:active}" @click.stop="close"></view>
    <view class="t-box" :class="{active:active}">
      <view class="t-header">
        <view class="t-header-button" @click.stop="close">取消</view>
        <view class="t-header-button" @click.stop="confirm">确认</view>
      </view>
      <view class="t-color__box" :style="{ background: 'rgb(' + bgcolor.r + ',' + bgcolor.g + ',' + bgcolor.b + ')'}">
        <view class="t-background boxs" @touchstart="touchstart($event, 0)" @touchmove="touchmove($event, 0)" @touchend="touchend($event, 0)">
          <view class="t-color-mask"></view>
          <view class="t-pointer" :style="{ top: site[0].top - 8 + 'px', left: site[0].left - 8 + 'px' }"></view>
        </view>
      </view>
      <view class="t-control__box">
        <view class="t-control__color">
          <view class="t-control__color-content" :style="{ background: 'rgba(' + rgba.r + ',' + rgba.g + ',' + rgba.b + ',' + rgba.a + ')' }"></view>
        </view>
        <view class="t-control-box__item">
          <view class="t-controller boxs" @touchstart="touchstart($event, 1)" @touchmove="touchmove($event, 1)" @touchend="touchend($event, 1)">
            <view class="t-hue">
              <view class="t-circle" :style="{ left: site[1].left - 12 + 'px' }"></view>
            </view>
          </view>
          <view class="t-controller boxs" @touchstart="touchstart($event, 2)" @touchmove="touchmove($event, 2)" @touchend="touchend($event, 2)">
            <view class="t-transparency">
              <view class="t-circle" :style="{ left: site[2].left - 12 + 'px' }"></view>
            </view>
          </view>
        </view>
      </view>
<!--      <view class="t-result__box">-->
<!--        <view v-if="mode" class="t-result__item">-->
<!--          <input class="t-result__box-input" v-model="hex">-->
<!--          <view class="t-result__box-text">HEX</view>-->
<!--        </view>-->
<!--        <template v-else>-->
<!--          <view class="t-result__item">-->
<!--            <view class="t-result__box-input">{{rgba.r}}</view>-->
<!--            <view class="t-result__box-text">R</view>-->
<!--          </view>-->
<!--          <view class="t-result__item">-->
<!--            <view class="t-result__box-input">{{rgba.g}}</view>-->
<!--            <view class="t-result__box-text">G</view>-->
<!--          </view>-->
<!--          <view class="t-result__item">-->
<!--            <view class="t-result__box-input">{{rgba.b}}</view>-->
<!--            <view class="t-result__box-text">B</view>-->
<!--          </view>-->
<!--          <view class="t-result__item">-->
<!--            <view class="t-result__box-input">{{rgba.a}}</view>-->
<!--            <view class="t-result__box-text">A</view>-->
<!--          </view>-->
<!--        </template>-->

<!--        <view class="t-result__item t-select" @click="select">-->
<!--          <view class="t-result__box-input">-->
<!--            <view>切换</view>-->
<!--            <view>模式</view>-->
<!--          </view>-->
<!--        </view>-->
<!--      </view>-->
      <view class="t-alternative">
        <view class="t-alternative__item" v-for="(item,index) in colorList" :key="index">
          <view class="t-alternative__item-content" :style="{ background: 'rgba(' + item.r + ',' + item.g + ',' + item.b + ',' + item.a + ')' }"
                @click="selectColor(item)">
          </view>
        </view>
      </view>
    </view>
  </view>
</template>

<script lang="ts">
export default {
  props: {
    color: {
      type: Object,
      default () {
        return {
          r: 0,
          g: 0,
          b: 0,
          a: 1
        }
      }
    },
    spareColor: {
      type: Array,
      default () {
        return []
      }
    }
  },
  data() {
    return {
      show: false,
      active: false,
      // rgba 颜色
      rgba: {
        r: 0,
        g: 0,
        b: 0,
        a: 1
      },
      // hsb 颜色
      hsb: {
        h: 0,
        s: 0,
        b: 0
      },
      site: [{
        top: 0,
        left: 0
      }, {
        left: 0
      }, {
        left: 0
      }],
      index: 0,
      bgcolor: {
        r: 255,
        g: 0,
        b: 0,
        a: 1
      },
      hex: '#000000',
      mode: true,
      colorList: [{
        r: 244,
        g: 67,
        b: 54,
        a: 1
      }, {
        r: 233,
        g: 30,
        b: 99,
        a: 1
      }, {
        r: 156,
        g: 39,
        b: 176,
        a: 1
      }, {
        r: 103,
        g: 58,
        b: 183,
        a: 1
      }, {
        r: 63,
        g: 81,
        b: 181,
        a: 1
      }, {
        r: 33,
        g: 150,
        b: 243,
        a: 1
      }, {
        r: 3,
        g: 169,
        b: 244,
        a: 1
      }, {
        r: 0,
        g: 188,
        b: 212,
        a: 1
      }, {
        r: 0,
        g: 150,
        b: 136,
        a: 1
      }, {
        r: 76,
        g: 175,
        b: 80,
        a: 1
      }, {
        r: 139,
        g: 195,
        b: 74,
        a: 1
      }, {
        r: 205,
        g: 220,
        b: 57,
        a: 1
      }, {
        r: 255,
        g: 235,
        b: 59,
        a: 1
      }, {
        r: 255,
        g: 193,
        b: 7,
        a: 1
      }, {
        r: 255,
        g: 152,
        b: 0,
        a: 1
      }, {
        r: 255,
        g: 87,
        b: 34,
        a: 1
      }, {
        r: 121,
        g: 85,
        b: 72,
        a: 1
      }, {
        r: 158,
        g: 158,
        b: 158,
        a: 1
      }, {
        r: 0,
        g: 0,
        b: 0,
        a: 0.5
      }, {
        r: 0,
        g: 0,
        b: 0,
        a: 0
      }, ]
    };
  },
  created() {
    this.rgba = this.color;
    if (this.spareColor.length !== 0) {
      this.colorList = this.spareColor;
    }
  },
  methods: {
    /**
     * 初始化
     */
    init() {
      this.rgba = this.color
      // hsb 颜色
      this.hsb = this.rgbToHex(this.rgba);
      // this.setColor();
      this.setValue(this.rgba);
    },
    moveHandle() {},
    open() {
      this.show = true;
      this.$nextTick(() => {
        this.init();
        setTimeout(() => {
          this.active = true;
          setTimeout(() => {
            this.getSelectorQuery();
          }, 350)
        }, 50)
      })

    },
    close() {
      this.active = false;
      this.$nextTick(() => {
        setTimeout(() => {
          this.show = false;
        }, 500)
      })
    },
    confirm() {
      this.close();
      this.$emit('confirm', {
        rgba: this.rgba,
        hex: this.hex
      })
    },
    // 选择模式
    select() {
      this.mode = !this.mode
    },
    // 常用颜色选择
    selectColor(item) {
      this.setColorBySelect(item)
    },
    touchstart(e, index) {
      const {
        pageX,
        pageY
      } = e.touches[0];
      this.pageX = pageX;
      this.pageY = pageY;
      this.setPosition(pageX, pageY, index);
    },
    touchmove(e, index) {
      const {
        pageX,
        pageY
      } = e.touches[0];
      this.moveX = pageX;
      this.moveY = pageY;
      this.setPosition(pageX, pageY, index);
    },
    touchend(e, index) {
      // console.log(e, index)
    },
    /**
     * 设置位置
     */
    setPosition(x, y, index) {
      this.index = index;
      const {
        top,
        left,
        width,
        height
      } = this.position[index];
      // 设置最大最小值

      this.site[index].left = Math.max(0, Math.min(parseInt(x - left), width));
      if (index === 0) {
        this.site[index].top = Math.max(0, Math.min(parseInt(y - top), height));
        // 设置颜色
        this.hsb.s = parseInt((100 * this.site[index].left) / width);
        this.hsb.b = parseInt(100 - (100 * this.site[index].top) / height);
        this.setColor();
        this.setValue(this.rgba);
      } else {
        this.setControl(index, this.site[index].left);
      }
    },
    /**
     * 设置 rgb 颜色
     */
    setColor() {
      const rgb = this.HSBToRGB(this.hsb);
      this.rgba.r = rgb.r;
      this.rgba.g = rgb.g;
      this.rgba.b = rgb.b;
    },
    /**
     * 设置二进制颜色
     * @param {Object} rgb
     */
    setValue(rgb) {
      this.hex = '#' + this.rgbToHex(rgb);
    },
    setControl(index, x) {
      const {
        top,
        left,
        width,
        height
      } = this.position[index];

      if (index === 1) {
        this.hsb.h = parseInt((360 * x) / width);
        this.bgcolor = this.HSBToRGB({
          h: this.hsb.h,
          s: 100,
          b: 100
        });
        this.setColor()
      } else {
        this.rgba.a = (x / width).toFixed(1);
      }
      this.setValue(this.rgba);
    },
    /**
     * rgb 转 二进制 hex
     * @param {Object} rgb
     */
    rgbToHex(rgb) {
      let hex = [rgb.r.toString(16), rgb.g.toString(16), rgb.b.toString(16)];
      hex.map(function(str, i) {
        if (str.length === 1) {
          hex[i] = '0' + str;
        }
      });
      return hex.join('');
    },
    setColorBySelect(getrgb) {
      const {
        r,
        g,
        b,
        a
      } = getrgb;
      let rgb = {}
      rgb = {
        r: r ? parseInt(r) : 0,
        g: g ? parseInt(g) : 0,
        b: b ? parseInt(b) : 0,
        a: a ? a : 0,
      };
      this.rgba = rgb;
      this.hsb = this.rgbToHsb(rgb);
      this.changeViewByHsb();
    },
    changeViewByHsb() {
      const [a, b, c] = this.position;
      this.site[0].left = parseInt(this.hsb.s * a.width / 100);
      this.site[0].top = parseInt((100 - this.hsb.b) * a.height / 100);
      this.setColor(this.hsb.h);
      this.setValue(this.rgba);
      this.bgcolor = this.HSBToRGB({
        h: this.hsb.h,
        s: 100,
        b: 100
      });

      this.site[1].left = this.hsb.h / 360 * b.width;
      this.site[2].left = this.rgba.a * c.width;

    },
    /**
     * hsb 转 rgb
     * @param hsb {Object} 颜色模式  H(hues)表示色相，S(saturation)表示饱和度，B（brightness）表示亮度
     */
    HSBToRGB(hsb) {
      let rgb = {};
      let h = Math.round(hsb.h);
      let s = Math.round((hsb.s * 255) / 100);
      let v = Math.round((hsb.b * 255) / 100);
      if (s === 0) {
        rgb.r = rgb.g = rgb.b = v;
      } else {
        let t1 = v;
        let t2 = ((255 - s) * v) / 255;
        let t3 = ((t1 - t2) * (h % 60)) / 60;
        if (h === 360) h = 0;
        if (h < 60) {
          rgb.r = t1;
          rgb.b = t2;
          rgb.g = t2 + t3;
        } else if (h < 120) {
          rgb.g = t1;
          rgb.b = t2;
          rgb.r = t1 - t3;
        } else if (h < 180) {
          rgb.g = t1;
          rgb.r = t2;
          rgb.b = t2 + t3;
        } else if (h < 240) {
          rgb.b = t1;
          rgb.r = t2;
          rgb.g = t1 - t3;
        } else if (h < 300) {
          rgb.b = t1;
          rgb.g = t2;
          rgb.r = t2 + t3;
        } else if (h < 360) {
          rgb.r = t1;
          rgb.g = t2;
          rgb.b = t1 - t3;
        } else {
          rgb.r = 0;
          rgb.g = 0;
          rgb.b = 0;
        }
      }
      return {
        r: Math.round(rgb.r),
        g: Math.round(rgb.g),
        b: Math.round(rgb.b)
      };
    },
    rgbToHsb(rgb) {
      let hsb = {
        h: 0,
        s: 0,
        b: 0
      };
      let min = Math.min(rgb.r, rgb.g, rgb.b);
      let max = Math.max(rgb.r, rgb.g, rgb.b);
      let delta = max - min;
      hsb.b = max;
      hsb.s = max !== 0 ? 255 * delta / max : 0;
      if (hsb.s !== 0) {
        if (rgb.r === max) hsb.h = (rgb.g - rgb.b) / delta;
        else if (rgb.g === max) hsb.h = 2 + (rgb.b - rgb.r) / delta;
        else hsb.h = 4 + (rgb.r - rgb.g) / delta;
      } else hsb.h = -1;
      hsb.h *= 60;
      if (hsb.h < 0) hsb.h = 0;
      hsb.s *= 100 / 255;
      hsb.b *= 100 / 255;
      return hsb;
    },
    getSelectorQuery() {
      const views = uni.createSelectorQuery().in(this);
      views
          .selectAll('.boxs')
          .boundingClientRect(data => {
            if (!data || data.length === 0) {
              setTimeout(() => this.getSelectorQuery(), 20)
              return
            }
            this.position = data;
            // this.site[0].top = data[0].height;
            // this.site[0].left = 0;
            // this.site[1].left = data[1].width;
            // this.site[2].left = data[2].width;
            this.setColorBySelect(this.rgba);
          })
          .exec();
    }
  },
  watch: {
    spareColor(newVal) {
      // console.log(newVal)
      this.colorList = newVal;
    }
  }
};
</script>

<style scoped>
.t-wrapper {
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  margin-bottom: 100rpx;
  width: 100%;
  box-sizing: border-box;
  z-index: 9999;
}

.t-box {
  width: 100%;
  position: absolute;
  bottom: 0;
  padding: 30rpx 0;
  padding-top: 0;
  background: #fff;
  transition: all 0.3s;
  transform: translateY(100%);
}

.t-box.active {
  transform: translateY(0%);
}

.t-header {
  display: flex;
  justify-content: space-between;
  width: 100%;
  height: 80rpx;
  border-bottom: 2rpx #eee solid;
  box-shadow: 2rpx 0 4rpx rgba(0, 0, 0, 0.1);
  background: #fff;
}

.t-header-button {
  display: flex;
  align-items: center;
  width: 150rpx;
  height: 80rpx;
  font-size: 30rpx;
  color: #666;
  padding-left: 20rpx;
}

.t-header-button:last-child {
  justify-content: flex-end;
  padding-right: 20rpx;
}

.t-mask {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.6);
  z-index: -1;
  transition: all 0.3s;
  opacity: 0;
}

.t-mask.active {
  opacity: 1;
}

.t-color__box {
  position: relative;
  height: 400rpx;
  background: rgb(255, 0, 0);
  overflow: hidden;
  box-sizing: border-box;
  margin: 20rpx 20rpx 0;
}

.t-background {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: linear-gradient(to right, #fff, rgba(255, 255, 255, 0));
}

.t-color-mask {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  width: 100%;
  height: 400rpx;
  background: linear-gradient(to top, #000, rgba(0, 0, 0, 0));
}

.t-pointer {
  position: absolute;
  bottom: -16rpx;
  left: -16rpx;
  z-index: 2;
  width: 30rpx;
  height: 30rpx;
  border: 2rpx #fff solid;
  border-radius: 50%;
}

.t-show-color {
  width: 100rpx;
  height: 50rpx;
}

.t-control__box {
  margin-top: 50rpx;
  width: 100%;
  display: flex;
  padding-left: 20rpx;
  box-sizing: border-box;
}

.t-control__color {
  flex-shrink: 0;
  width: 100rpx;
  height: 100rpx;
  border-radius: 50%;
  background-color: #fff;
  background-image: linear-gradient(45deg, #eee 25%, transparent 25%, transparent 75%, #eee 75%, #eee),
  linear-gradient(45deg, #eee 25%, transparent 25%, transparent 75%, #eee 75%, #eee);
  background-size: 36rpx 36rpx;
  background-position: 0 0, 18rpx 18rpx;
  border: 2rpx #eee solid;
  overflow: hidden;
}

.t-control__color-content {
  width: 100%;
  height: 100%;
}

.t-control-box__item {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  width: 100%;
  padding: 0 15rpx;
}

.t-controller {
  position: relative;
  width: 100%;
  height: 30rpx;
  background-color: #fff;
  background-image: linear-gradient(45deg, #eee 25%, transparent 25%, transparent 75%, #eee 75%, #eee),
  linear-gradient(45deg, #eee 25%, transparent 25%, transparent 75%, #eee 75%, #eee);
  background-size: 32rpx 32rpx;
  background-position: 0 0, 16rpx 16rpx;
}

.t-hue {
  width: 100%;
  height: 100%;
  background: linear-gradient(to right, #f00 0%, #ff0 17%, #0f0 33%, #0ff 50%, #00f 67%, #f0f 83%, #f00 100%);
}

.t-transparency {
  width: 100%;
  height: 100%;
  background: linear-gradient(to right, rgba(0, 0, 0, 0) 0%, rgb(0, 0, 0));
}

.t-circle {
  position: absolute;
  /* right: -10px; */
  top: -4rpx;
  width: 40rpx;
  height: 40rpx;
  box-sizing: border-box;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 0 4rpx 2rpx rgba(0, 0, 0, 0.1);
}

.t-result__box {
  margin-top: 20rpx;
  padding: 10rpx;
  width: 100%;
  display: flex;
  box-sizing: border-box;
}

.t-result__item {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 10rpx;
  width: 100%;
  box-sizing: border-box;
}

.t-result__box-input {
  padding: 10rpx 0;
  width: 100%;
  font-size: 28rpx;
  box-shadow: 0 0 2rpx 2rpx rgba(0, 0, 0, 0.1);
  color: #999;
  text-align: center;
  background: #fff;
}

.t-result__box-text {
  margin-top: 10rpx;
  font-size: 28rpx;
  line-height: 2;
}

.t-select {
  flex-shrink: 0;
  width: 150rpx;
  padding: 0 30rpx;
}

.t-select .t-result__box-input {
  border-radius: 10rpx;
  border: none;
  color: #999;
  box-shadow: 2rpx 2rpx 4rpx 2rpx rgba(0, 0, 0, 0.1);
  background: #fff;
}

.t-select .t-result__box-input:active {
  box-shadow: 0 0 1px 0 rgba(0, 0, 0, 0.1);
}

.t-alternative {
  display: flex;
  flex-wrap: wrap;
  /* justify-content: space-between; */
  margin-top: 10rpx;
  width: 100%;
  padding-right: 10rpx;
  box-sizing: border-box;
}

.t-alternative__item {
  margin-left: 12rpx;
  margin-top: 10rpx;
  width: 50rpx;
  height: 50rpx;
  border-radius: 10rpx;
  background-color: #fff;
  background-image: linear-gradient(45deg, #eee 25%, transparent 25%, transparent 75%, #eee 75%, #eee),
  linear-gradient(45deg, #eee 25%, transparent 25%, transparent 75%, #eee 75%, #eee);
  background-size: 36rpx 36rpx;
  background-position: 0 0, 18rpx 18rpx;
  border: 1px #eee solid;
  overflow: hidden;
}

.t-alternative__item-content {
  width: 50rpx;
  height: 50rpx;
  background: rgba(255, 0, 0, 0.5);
}

.t-alternative__item:active {
  transition: all 0.3s;
  transform: scale(1.1);
}
</style>
